﻿using System;
using System.Globalization;
using System.Windows.Data;

namespace vBridge.Wpf.ValueConverters
{
    /// <summary>
    ///     Provides a way to apply custom logic to a binding.
    /// </summary>
    /// <remarks>
    ///     This class provides type-checking for value converters.
    /// </remarks>
    /// <typeparam name="TSource">The source type that will be converted to the destination type.</typeparam>
    /// <typeparam name="TDestination">The destination type.</typeparam>
    /// <seealso cref="IValueConverter" />
    public abstract class ValueConverterBase<TSource, TDestination> : IValueConverter
    {
        public Object Convert(Object value, Type targetType, Object parameter, CultureInfo culture)
        {
            var source = (TSource) value;
            return SourceToDestination(source, targetType, parameter, culture);
        }

        public Object ConvertBack(Object value, Type targetType, Object parameter, CultureInfo culture)
        {
            var destination = (TDestination) value;
            return DestinationToSource(destination, targetType, parameter, culture);
        }

        /// <summary>
        ///     Converts the source type to the destination type.
        /// </summary>
        /// <param name="value">The value that is produced by the binding target.</param>
        /// <param name="targetType">The type to convert to.</param>
        /// <param name="parameter">The converter parameter to use.</param>
        /// <param name="culture">The culture to use in the converter.</param>
        /// <returns>The converted source object.</returns>
        protected abstract TDestination SourceToDestination(TSource value, Type targetType, Object parameter,
            CultureInfo culture);

        /// <summary>
        ///     Converts the destination type to the source type.
        /// </summary>
        /// <param name="value">The value that is produced by the binding target.</param>
        /// <param name="targetType">The type to convert to.</param>
        /// <param name="parameter">The converter parameter to use.</param>
        /// <param name="culture">The culture to use in the converter.</param>
        /// <returns>The back-converted destination object.</returns>
        protected abstract TSource DestinationToSource(TDestination value, Type targetType, Object parameter,
            CultureInfo culture);
    }
}